
函数模板重载的一个常见动机是，基于所涉及的类型知识提供算法的更特化版本。使用简单的swap()来交换两个值:

\begin{lstlisting}[style=styleCXX]
template<typename T>
void swap(T& x, T& y)
{
	T tmp(x);
	x = y;
	y = tmp;
}
\end{lstlisting}

这个实现涉及三个复制操作。对于某些类型，可以提供更有效的swap()操作，例如Array<T>将其数据存储为指向数组内容和长度的指针:

\begin{lstlisting}[style=styleCXX]
template<typename T>
void swap(Array<T>& x, Array<T>& y)
{
	swap(x.ptr, y.ptr);
	swap(x.len, y.len);
}
\end{lstlisting}

swap()的两个实现都将交换两个Array<T>对象的内容。但后一种实现更高效，因为它使用了Array<T>的属性(特别是ptr和len及其各种成员)，而这些属性对于其他类型不可用。

\begin{tcolorbox}[colback=webgreen!5!white,colframe=webgreen!75!black]
\hspace*{0.75cm}swap()的一个更好的选择是使用std::move()来避免在主模板中进行复制，这里提出的替代方案适用范围更广。
\end{tcolorbox}

因此，后一个函数模板(在概念上)比前一个更特化，前一个函数模板接受的类型子集执行相同的操作。基于函数模板的部分排序规则，第二个函数模板也更加特化了(参见16.2.2节)，因此编译器将选择更特化(因此更高效)的函数模板(例如，Array<T>参数)，而当更特化的版本不适用时，会回退到更通用(可能更低效)的算法。

为通用算法引入更特化的设计和优化方法称为算法特化。更特化的版本应用于泛型算法的有效输入子集，根据特定的类型或类型的属性可以识别这个子集，其通常比泛型算法的一般实现更有效。

对于实现算法特化至关重要，当有更特化的变量适用时，调用者无需了解这些变量的存在就会自动选择。swap()的示例中，这是通过使用通用函数模板(第一个swap())重载(概念上)更特化的函数模板(第二个swap())来实现的，并确保更特化的函数模板根据C++的部分排序规则也更特化。

并不是所有概念上更特化的算法版本，都可以直接转换为提供正确的部分排序行为的函数模板。对于下一个示例，advanceIter()函数(类似于C++标准库中的std::advance())，将迭代器x向前移动n步。这个通用算法可以操作输入迭代器:

\begin{lstlisting}[style=styleCXX]
template<typename InputIterator, typename Distance>
void advanceIter(InputIterator& x, Distance n)
{
	while (n > 0) { // linear time
		++x;
		--n;
	}
}
\end{lstlisting}

对于提供随机访问操作的特定迭代器类，可以提供更高效的实现:

\begin{lstlisting}[style=styleCXX]
template<typename RandomAccessIterator, typename Distance>
void advanceIter(RandomAccessIterator& x, Distance n) {
	x += n; // constant time
}
\end{lstlisting}

定义这两个函数模板将导致编译器报错，因为仅根据模板参数名称，而不同的函数模板不可重载。本章的其余部分将讨论模拟重载这些函数模板所需的技术。











